﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevExpress.XtraEditors.Controls;

namespace RadinfFakturer
{
    public partial class Fakturer : Form
    {
        #region Members
        private ErrorProvider _errorProvider = new ErrorProvider();

        public static FakturerDataSet DataSource = new FakturerDataSet();
        public static List<string> Logs = new List<string>();
        #endregion

        #region Constructor
        public Fakturer()
        {
            InitializeComponent();
            initializeLookUps();
            loadData();
            setDataBinding();
            initializeInvoice();
        }

        private void initializeInvoice()
        {
            FakturerDataSet.INVOICERow invoiceDR = DataSource.INVOICE.NewINVOICERow();
            invoiceDR.CREATE_DATE = DateTime.Today;
            invoiceDR.SELL_DATE = DateTime.Today;
            invoiceDR.TYPE = this.leType.Properties.Items[0];
            DataSource.INVOICE.Rows.Add(invoiceDR);
        }

        private void setDataBinding()
        {
            deCreateDate.DataBindings.Add(new Binding("EditValue", DataSource.INVOICE, "CREATE_DATE"));
            deSellDate.DataBindings.Add(new Binding("EditValue", DataSource.INVOICE, "SELL_DATE"));
            textEdit3.DataBindings.Add(new Binding("EditValue", DataSource.INVOICE, "INVOICE_NUMBER"));
            leType.DataBindings.Add(new Binding("EditValue", DataSource.INVOICE, "TYPE"));

            gcContractor.DataSource = DataSource.CONTRACTOR;
            gcItem.DataSource = DataSource.ITEM;
        }

        private void initializeLookUps()
        {
            ComboBoxItemCollection docTypeCollection = this.leType.Properties.Items;
            docTypeCollection.BeginUpdate();
            try
            {
                foreach (DocumentType docType in Globals.DOC_TYPES)
                {
                    docTypeCollection.Add(docType);
                }
            }
            finally
            {
                docTypeCollection.EndUpdate();
            }            

            ComboBoxItemCollection vatCollection = this.repVAT.Items;
            vatCollection.BeginUpdate();
            try
            {
                foreach(Vat vat in Globals.VAT)
                {
                    vatCollection.Add(vat);
                }
            }
            finally
            {
                vatCollection.EndUpdate();
            }

            ComboBoxItemCollection measureCollection = this.repMeasure.Items;
            measureCollection.BeginUpdate();
            try
            {
                foreach (string measure in Globals.MEASURE)
                {
                    measureCollection.Add(measure);
                }
            }
            finally
            {
                measureCollection.EndUpdate();
            }
        }
        #endregion

        #region Load / Save
        private void loadData()
        {
            string dataFilePath = Globals.XML_FILES.RADINF_FAKTURER_DATA;
            try
            {
                Cursor.Current = Cursors.WaitCursor;
                if (!File.Exists(dataFilePath))
                    createDataFile(Globals.XML_FILES.RADINF_FAKTURER_DATA_DIR, dataFilePath);

                DataSource.ReadXml(dataFilePath);
                //validateLoadedBackUp(dataFilePath);

                Cursor.Current = Cursors.Default;
            }
            catch (Exception exc)
            {
                RadinfTools.ShowError("Fakturer.loadData()", exc.Message);
            }
        }

        private void saveData()
        {
            DataSource.ITEM.Clear();
            DataSource.INVOICE.Clear();
            DataSource.AcceptChanges();

            string dataFilePath = Globals.XML_FILES.RADINF_FAKTURER_DATA;
            try
            {
                if (!File.Exists(dataFilePath))
                    createDataFile(Globals.XML_FILES.RADINF_FAKTURER_DATA_DIR, dataFilePath);

                DataSource.WriteXml(dataFilePath);
            }
            catch (Exception exc)
            {
                RadinfTools.ShowError("Fakturer.saveData()", exc.Message);
            }
        }

        private void createDataFile(string directory, string fileName)
        {
            FileInfo fi = new FileInfo(fileName);
            if (Directory.Exists(directory))
            {
                fi.Create();
            }
            else
            {
                Directory.CreateDirectory(directory);
                fi.Create();
            }
        }
        #endregion

        #region Tools
        private void setGridFilter(string filter)
        {
            ((DataView)this.gvContractor.DataSource).RowFilter = filter;
        }

        private double countNetto(double brutto, Vat vat)
        {
            double value = -1;
            value = brutto / (vat.Value + 1);
            return Math.Round(value, 2, MidpointRounding.AwayFromZero);
        }

        private double countVat(double brutto,Vat vat)
        {
            double value = -1;
            value = (brutto * (vat.Value * 100)) / (100 + (vat.Value * 100));
            return Math.Round(value, 2, MidpointRounding.AwayFromZero); 
        }
        #endregion

        #region Validation
        private bool validateAllCtrls()
        {
            bool result = true;
            _errorProvider.Clear();
            result &= validateInvoiceNumber();
            result &= validateContractor();
            return result;
        }

        private bool validateInvoiceNumber()
        {
            bool result = true;

            if(String.IsNullOrWhiteSpace(RadinfTools.ConvertToString(textEdit3.EditValue)))
            {
                result = false;
                _errorProvider.SetError(this.textEdit3, Globals.ERRORS.REQUIRED);
            }

            return result;
        }

        private bool  validateContractor()
        {
            bool result = true;
            int contractorID;
            try
            {
                result = Int32.TryParse(RadinfTools.ConvertToString(DataSource.INVOICE[0].CONTRACTOR), out contractorID);
            }
            catch (Exception exc)
            {
                result = false;
            }
            
            if (!result)
                _errorProvider.SetError(this.lbl1, Globals.ERRORS.CONTRACTOR);
            
            return result;
        }
        #endregion

        #region Events
        private void btnSelectContractor_Click(object sender, EventArgs e)
        {
            if (gvContractor.GetDataRow(gvContractor.FocusedRowHandle) != null &&
                gvContractor.GetDataRow(gvContractor.FocusedRowHandle) is FakturerDataSet.CONTRACTORRow)
            {
                FakturerDataSet.CONTRACTORRow contractorDR = (FakturerDataSet.CONTRACTORRow)gvContractor.GetDataRow(gvContractor.FocusedRowHandle);
                lblName.Text = RadinfTools.ConvertToString(contractorDR.NAME);
                lblAddress.Text = RadinfTools.ConvertToString(contractorDR.ADDRESS);
                lblZipCode.Text = RadinfTools.ConvertToString(contractorDR.ZIP_CODE);
                lblCity.Text = RadinfTools.ConvertToString(contractorDR.CITY);
                lblNIP.Text = "NIP: " + RadinfTools.ConvertToString(contractorDR.NIP);

                DataSource.INVOICE[0].CONTRACTOR = RadinfTools.ConvertToInt(contractorDR.ID);
            }
        }

        private void btnClose_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnPrint_Click(object sender, EventArgs e)
        {
            if (validateAllCtrls())
            {
                MessageBox.Show("DRUKUJE");
            }
        }

        private void Fakturer_FormClosing(object sender, FormClosingEventArgs e)
        {
            saveData();
        }

        private void searching(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e)
        {
            if (sender is DevExpress.XtraEditors.TextEdit)
            {
                DevExpress.XtraEditors.TextEdit textEdit = sender as DevExpress.XtraEditors.TextEdit;

                string searchCriteria = RadinfTools.ConvertToString(e.NewValue);
                if (!String.IsNullOrEmpty(searchCriteria) && !String.IsNullOrEmpty(RadinfTools.ConvertToString(textEdit.Tag)))
                {
                    searchCriteria = RadinfTools.ConvertToString(textEdit.Tag) + " LIKE '" + searchCriteria + "%'";
                    setGridFilter(searchCriteria);
                }
                else
                    setGridFilter(string.Empty);
            }
        }

        private void gvItem_RowUpdated(object sender, DevExpress.XtraGrid.Views.Base.RowObjectEventArgs e)
        {
            if (((DataRowView)e.Row).Row is FakturerDataSet.ITEMRow)
            {
                double brutto;
                double quantity;

                FakturerDataSet.ITEMRow itemDR = ((DataRowView)e.Row).Row as FakturerDataSet.ITEMRow;
                if (itemDR != null)
                {
                    itemDR.BeginEdit();
                    itemDR.INVOICE = RadinfTools.ConvertToInt(DataSource.INVOICE[0].ID);
                    Vat vat = itemDR.VAT as Vat;
                    try
                    {
                        bool bruttoParse = Double.TryParse(RadinfTools.ConvertToString(itemDR.BRUTTO), out brutto);
                        bool quantityParse = Double.TryParse(RadinfTools.ConvertToString(itemDR.QUANTITY), out quantity);
                        if (bruttoParse && quantityParse)
                        {
                            double netto = countNetto(brutto, vat);

                            itemDR.NETTO = netto;
                            itemDR.VAT_VALUE = Math.Round((countVat(brutto, vat) * quantity), 2, MidpointRounding.AwayFromZero);
                            itemDR.NETTO_VALUE = Math.Round((netto * quantity), 2, MidpointRounding.AwayFromZero);
                            itemDR.BRUTTO_VALUE = Math.Round((brutto * quantity), 2, MidpointRounding.AwayFromZero);
                        }
                    }
                    catch (Exception ignore) { }
                    finally
                    {
                        itemDR.EndEdit();
                    }
                }
            }
        }

        private void gvItem_InitNewRow(object sender, DevExpress.XtraGrid.Views.Grid.InitNewRowEventArgs e)
        {
            FakturerDataSet.ITEMRow itemDR = gvItem.GetDataRow(e.RowHandle) as FakturerDataSet.ITEMRow;
            itemDR.VAT = this.repVAT.Items[0];
            itemDR.MEASURE = this.repMeasure.Items[0].ToString();
        }
        #endregion                
    }
}
